/* $Header: sig_digital.h,v 2.2 01/10/02 10:33:04 przybyls Exp $ */

/***********************************************************************/
/* INCLUDE FILE NAME:  sig_digital.h                                   */
/* ==================                                                  */
/*                                                                     */
/* Author:  Lesley Freed                                               */
/*                                                                     */
/* COMMENT:  Define the digital signal path processing MACRO.          */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

#ifndef SIG_DIG_H
#define SIG_DIG_H

/*****************************/
/*   IFDEFS                  */
/*****************************/


/*****************************/
/*   SYMBOLIC CONSTANTS      */
/*****************************/



/*****************************/
/*   MACROS                  */
/*****************************/

/***********************************************************************/
/* MACRO:  SUBTRACT_AND_CLAMP                                          */
/* ======                                                              */
/*                                                                     */
/* PURPOSE:  To perform and signed 32-bit subraction and clamp on      */
/*           underflow and overflow.                                   */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

#define SUBTRACT_AND_CLAMP( signal, value )                                    \
{                                                                              \
   if ( (signal) < 0 )                                                         \
   {                                                                           \
      (signal) -= (value);                                                     \
                                                                               \
      /* See if there was underflow */                                         \
      if ( ( (signal) >= 0 )  && ( (value) >= 0 ) )                            \
      {                                                                        \
         /* underflow occurred - the data has changed sign */                  \
         (signal) = (INT32)MIN_SIGNED_32BIT_VALUE;                             \
      }                                                                        \
   }                                                                           \
   else  /* signal >= 0 */                                                     \
   {                                                                           \
      (signal) -= (value);                                                     \
                                                                               \
      if ( ( (signal) < 0 )  && ( (value) < 0 ) )                              \
      {                                                                        \
         /* overflow occurred - the data has changed sign */                   \
         (signal) = MAX_SIGNED_32BIT_VALUE;                                    \
      }                                                                        \
   }                                                                           \
} 


   
/***********************************************************************/
/* MACRO:    DigitalSignalBunch                                        */
/* ======                                                              */
/*                                                                     */
/* PURPOSE: To perform bunching on a 48-bit digital signal.            */
/*                                                                     */
/* OPERATION: This has been made into a MACRO to eliminate the         */
/*            overhead of a function call.  The overall control        */
/*            of the bunching is as follows:                           */
/*                                                                     */
/* 1)  add X consecutive 20 Hz digital signals up into a running sum   */
/* called bunch_sum                                                    */
/*                                                                     */
/* 2)  apply a 3-pt boxcar filter to the bunch_sum:                    */
/*     - add up three bunch_sums                                       */
/*                                                                     */
/* 3)  scale the boxcar filter sum as follows:                         */
/*     if it is a detector signal:                                     */
/*     - divide by 32*X     where X is the number of signals bunched   */
/*     if it is a non-detector signal:                                 */
/*     - divide by 3*11*X   where X is the number of signals bunched   */
/*                                                                     */
/*  The reasoning for the difference between detector signals (from the*/
/*  detector dsp) and non-detector signals (e.g oven temp) is that for */
/*  detector signals we want to have the same gain as non-bunched      */
/*  detector signals (data rate >= 20 Hz).  The gain from the detector */
/*  dsp for signal with data rates >= 20 Hz is 33/32.  The gain from   */
/*  the detector dsp for signals with data rates < 10 Hz is 1, after   */
/*  we have applied the 3-pt box car filter it is again 33/32.  For    */
/*  non-detector signals we want to have a gain of 1.  Thus the scale  */
/*  factor applied to the boxcar filter sum is 33*X.                   */
/*                                                                     */
/*                                                                     */
/***********************************************************************/

#define ResetSignalBunch()                                              \
{                                                                       \
   pSignal->bunch_table[0].hi = pSignal->bunch_sum.hi;                  \
   pSignal->bunch_table[0].lo = pSignal->bunch_sum.lo;                  \
   pSignal->bunch_table[1].hi = pSignal->bunch_sum.hi;                  \
   pSignal->bunch_table[1].lo = pSignal->bunch_sum.lo;                  \
   pSignal->bunch_table[2].hi = pSignal->bunch_sum.hi;                  \
   pSignal->bunch_table[2].lo = pSignal->bunch_sum.lo;                  \
                                                                        \
   pSignal->filt_bunch_sum = ResetBoxCarSum3( &(pSignal->bunch_sum) );  \
   pSignal->bunch_reset = 0;                                            \
}                                                                       \
           
#define DigitalSignalBunch()                                            \
{                                                                       \
        if ( pSignal->bunch_reset )                                     \
        {                                                               \
           ResetSignalBunch()                                           \
        }                                                               \
        else                                                            \
        {                                                               \
           BoxCarSum3(&(pSignal->bunch_sum), &(pSignal->filt_bunch_sum),\
                      &(pSignal->bunch_table[pSignal->bunch_index]));   \
        }                                                               \
                                                                        \
        s_temp = pSignal->active_wkfile->bunch_count;                   \
                                                                        \
        if ( s_dsp )                                                    \
        {                                                               \
           s_temp *= 32;                                                \
           BunchOut(s_temp, 0x8400, &(pSignal->filt_bunch_sum),         \
                    &(pSignal->bunch_out));                             \
        }                                                               \
        else                                                            \
        {                                                               \
           s_temp *= 33;                                                \
           BunchOut(s_temp, 0x8000, &(pSignal->filt_bunch_sum),         \
                    &(pSignal->bunch_out));                             \
        }                                                               \
                                                                        \
        sig.data.hi_long =  pSignal->bunch_out.output.hi_long;          \
        sig.data.lo_word =  pSignal->bunch_out.output.lo_word;          \
			                                                \
        /* Update the bunch_index for the filter table */               \
			                                                \
        if ( pSignal->bunch_index)                                      \
        {                                                               \
           pSignal->bunch_index--;                                      \
        }                                                               \
        else                                                            \
        {                                                               \
           pSignal->bunch_index = 2;                                    \
        }                                                               \
			                                                \
        pSignal->bunch_count  = 0;                                      \
	pSignal->bunch_sum.lo = 0;                                      \
	pSignal->bunch_sum.hi = 0;                                      \
			                                                \
}



/***********************************************************************/
/* MACRO:    DigitalSigPath                                            */
/* ======                                                              */
/*                                                                     */
/* PURPOSE: To process the digital signal path data.                   */
/*                                                                     */
/* OPERATION:  Since this routine is called multiple times, (up to     */
/* ten times at 1kHz data rate) it has been made into a MACRO to       */
/* eliminate the overhead of a function call.  The overall control     */
/* flow is the following:                                              */
/*                                                                     */
/* 1) Select the appropriate signal, either a detector signal or       */
/*    an alternate plot signal of 32, 16 or 8-bit length.              */
/*                                                                     */
/* 2) Check for "Bunched" data.  In this case the bunch_count is       */
/*    greater than one.  First we add the new signal point to the      */
/*    bunch sum and increment the bunch count.                         */
/*                                                                     */
/* 2b)  IF the bunch_count = bunch_count setpoint THEN                 */
/*         calculate a new data point                                  */
/*      ELSE set the sig_count to zero (no data available)             */
/*           Note:  Bunching is done only for 20 Hz input data.  Thus, */
/*                  for bunched data we should have received one data  */
/*                  point per interrupt from the Signal DSP.           */
/*                                                                     */
/* 3) IF sig_count > 0 THEN                                            */
/*         Apply SCC                                                   */
/*         Normalize the Gain                                          */
/*         Store the data in buffer digital_data                       */
/*                                                                     */
/* LIMITATIONS:  Assumes that for bunched data the data rate has been  */
/*               set to 20Hz.  Assumes that the ptr pSignal has been   */
/*               set to point to the appropriate signal data struct.   */
/*                                                                     */
/***********************************************************************/

#define DigitalSigPath( i )                                                          \
{                                                                                    \
        /* Get the signal type */                                                    \
	s_temp = (U_INT8)pSignal->signal;		                                         \
                                                                                     \
        /* Set s_dsp flag true if it is a detector signal */                         \
	if (s_temp <= (U_INT8)MAX_DSP_SIGNAL_TYPE)                                       \
	{                                                                                \
	   s_dsp = TRUE;                                                                 \
	}                                                                                \
	else                                                                             \
	{                                                                                \
	   s_dsp = FALSE;                                                                \
	}                                                                                \
                                                                                     \
	if (s_temp <= (U_INT8)MAX_DET_SIGNAL_TYPE)                                       \
	{                                                                                \
	   /* Get the MS 32-bits from the detector */                                    \
	   sig.data.hi_long = pSignal->dsp_data->sig_out_hi[(i)];                        \
                                                                                     \
	   /* Get the LS 16-bits from the detector */                                    \
	   sig.data.lo_word = pSignal->dsp_data->sig_out_lo[(i)];                        \
	                                                                                 \
	}                                                                                \
	else                                                                             \
	{                                                                                \
	   sig.data.hi_long = pSignal->plot_out;                                         \
	   sig.data.lo_word = 0;                                                         \
	}                                                                                \
                                                                                     \
	if (pSignal->active_wkfile->bunch_count > 1)                                     \
	{                                                                                \
	                                                                                 \
	        pSignal->bunch_sum = BunchSum(sig.num.hi_word,                           \
                                              sig.num.lo_long,                       \
                                              pSignal->bunch_sum.hi,                 \
	                                      pSignal->bunch_sum.lo);                    \
                                                                                     \
		pSignal->bunch_count++;                                                      \
                                                                                     \
		if (pSignal->bunch_count ==                                                  \
                                    pSignal->active_wkfile->bunch_count)             \
		{                                                                            \
                    DigitalSignalBunch();                                            \
		}                                                                            \
		else                                                                         \
		{                                                                            \
	            pSignal->dsp_data->sig_count = 0;                                    \
		}                                                                            \
	}                                                                                \
                                                                                     \
    if (pSignal->dsp_data->sig_count)	                                             \
	{                                                                                \
		if ( pSignal->ccomp_mode )                                                   \
		{                                                                            \
			ApplySCC( &(sig.data) );                                                 \
                                                                                     \
                        if ( pSignal->signal == TEST_PLOT_SIGNAL )                   \
                        {                                                            \
                           sig.data.hi_long /= 256;                                  \
                        }                                                            \
		}                                                                            \
                if ( pSignal->zero_attn_on_off & ZERO_ON_MASK )                      \
                {                                                                    \
                   SUBTRACT_AND_CLAMP(sig.data.hi_long, pSignal->zero);              \
                }                                                                    \
                                                                                     \
        if ( pSignal->zero_attn_on_off & RESUM2_RESUME_MASK )                        \
        {         																	 \
           if ( pSignal->zero_attn_on_off & FREEZE_SIG_ON_MASK  )                    \
           {                     													 \
              *((pSignal->chan == SIGNAL1) ? &hold_idx1:&hold_idx2) = i;             \
              pSignal->zero_attn_on_off &= FREEZE_SIG_OFF_MASK;                      \
           }                                                                         \
           else                                                                      \
           {                                                                         \
              sig.data = pSignal->dig_data[( (pSignal->chan == SIGNAL1) ?            \
                                                        hold_idx1 : hold_idx2 ) ] ;  \
              pSignal->zero_attn_on_off += RESUME_SIG_ON_MASK ;                      \
           }                                                                         \
        }                                                                            \
                                                                                     \
        (pSignal->dig_data[( i )]) = sig.data;                                       \
	}                                                                                \
}




/***********************************************************************/
/* MACRO:  FilterSignal                                                */
/* ======                                                              */
/*                                                                     */
/* PURPOSE:  To smooth out the analog input signal, sig1_out_100, or   */
/*           sig2_out_100 for display and zero entry purposes.         */
/*                                                                     */
/* RETURNED VALUE: 32-bit filtered signal.                             */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/


#define FILTER_SIGNAL( signal, psignal )                                       \
{                                                                              \
                                                                               \
   psignal->filt_sum = FiltSum(signal,psignal->filt_table[ psignal->ptr_filt], \
                               psignal->filt_sum.hi,psignal->filt_sum.lo);     \
                                                                               \
                                                                               \
   /* Store the new data point in the array */                                 \
   psignal->filt_table[ psignal->ptr_filt ] = signal;                          \
                                                                               \
   psignal->filt_out = BunchOut32(psignal->filt_sum.hi,psignal->filt_sum.lo,   \
                                  ARRAY_SIZE_SIG_DISP,                         \
                                  psignal->filt_out.remainder);                \
                                                                               \
	/* Update the filter array pointer to point to the new oldest */       \
	/*  data point.  If the pointer is to the top of the array    */       \
	/*  put it down to the bottom of the array which is actually  */       \
	/*  a circular buffer, otherwise move it up one position.     */       \
                                                                               \
	if ( psignal->ptr_filt  )                                              \
	{                                                                      \
           psignal->ptr_filt--;		                                       \
	}                                                                      \
	else                                                                   \
	{                                                                      \
	   psignal->ptr_filt = ARRAY_SIZE_SIG_DISP-1;		               \
	}                                                                      \
                                                                               \
}


/***********************************************************************/
/* MACRO:     MONITOR_SIGNAL                                           */
/* ======                                                              */
/*                                                                     */
/* PURPOSE:  To capture the peak-to-peak noise of a signal.            */
/*                                                                     */
/* GLOBALS USED:  pSIG_TABLE                                           */
/*                                                                     */
/* LIMITATIONS:  Will overflow for noise greater than 31 bits pk-to-pk */
/*                                                                     */
/***********************************************************************/

#define MONITOR_SIGNAL( signal, psignal )                                      \
{                                                                              \
   psignal->reading_count++;                                                   \
                                                                               \
   psignal->last_reading = signal;                                             \
                                                                               \
   if ( signal > psignal->max_reading )                                        \
   {                                                                           \
      psignal->max_reading = signal;                                           \
   }                                                                           \
                                                                               \
   if ( signal < psignal->min_reading )                                        \
   {                                                                           \
      psignal->min_reading = signal;                                           \
   }                                                                           \
                                                                               \
   if ( psignal->reading_count > 200 )                                         \
   {                                                                           \
      psignal->noise         = psignal->max_reading - psignal->min_reading;    \
      psignal->reading_count = 0;                                              \
      psignal->max_reading   = (INT32)MIN_SIGNED_32BIT_VALUE;                  \
      psignal->min_reading   = MAX_SIGNED_32BIT_VALUE;                         \
                                                                               \
   }                                                                           \
}                                                                              \

/*****************************/
/*   TYPEDEFS                */
/*****************************/


/*****************************/
/*   FUNCTION PROTOTYPES     */
/*****************************/

#endif
